package com.yjkf.zh.admin.service.impl;

import com.yjkf.zh.admin.dao.SysDeviceMapper;
import com.yjkf.zh.admin.dao.SysPointUnitMapper;
import com.yjkf.zh.admin.dao.SysUserDeviceMapper;
import com.yjkf.zh.admin.dao.SysUserMapper;
import com.yjkf.zh.admin.model.SysDevice;
import com.yjkf.zh.admin.model.SysDevicePointUnit;
import com.yjkf.zh.admin.model.SysUser;
import com.yjkf.zh.admin.model.SysUserDevice;
import com.yjkf.zh.admin.service.SysUserDeviceService;
import com.yjkf.zh.core.http.HttpResult;
import com.yjkf.zh.core.page.MybatisPageHelper;
import com.yjkf.zh.core.page.PageRequest;
import com.yjkf.zh.core.page.PageResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

@Service
public class SysUserDeviceServiceImpl implements SysUserDeviceService {

    @Autowired
    private SysUserDeviceMapper sysUserDeviceMapper;

    @Autowired
    private SysDeviceMapper sysDeviceMapper;

    @Autowired
    private SysPointUnitMapper sysPointUnitMapper;

    @Autowired
    private SysUserMapper sysUserMapper;


    @Override
    public List<SysUserDevice> findDeviceTree(String deviceName, Long userId){
        List<SysUserDevice> sysUserDeviceList = new ArrayList<>();
        List<SysUserDevice> sysUserDevices = findDevicesForUser(deviceName,userId);
        for(SysUserDevice sysUserDevice:sysUserDevices){
            if(sysUserDevice.getParentDeviceId()==0||sysUserDevice.getParentDeviceId()==null||sysUserDevice.getType()==0||!sysUserDevice.getCreateId().equals(userId)){
                if(!exists(sysUserDeviceList,sysUserDevice)){
                    sysUserDevice.setLevel(0);
                    sysUserDeviceList.add(sysUserDevice);
                }
            }
        }
        sysUserDeviceList.sort((o1, o2) -> o1.getOrderNum().compareTo(o2.getOrderNum()));
        findChildren(sysUserDeviceList,sysUserDevices);
        return  sysUserDeviceList;
    }

    @Override
    public SysUserDevice findForParentDeviceId(Long parentDeviceId) {
        return sysUserDeviceMapper.findForParentDeviceId(parentDeviceId);
    }

    @Override
    public List<SysUserDevice> findListForParentDeviceId(Long parentDeviceId) {
        return sysUserDeviceMapper.findListForParentDeviceId(parentDeviceId);
    }



    private void findChildren(List<SysUserDevice> sysUserDeviceList,List<SysUserDevice> sysUserDevices){
        for(SysUserDevice sysUserDevice:sysUserDeviceList){

            List<SysUserDevice> children = new ArrayList<>();
            for(SysUserDevice sysUserDevice1:sysUserDevices){
               // if(sysUserDevice.getParentDeviceId()!=0&&sysUserDevice.getParentDeviceId().equals(sysUserDevice1.getDeviceId())){
                if(sysUserDevice.getId()!=null&&sysUserDevice.getId().equals(sysUserDevice1.getParentDeviceId())){
                    sysUserDevice1.setParentName(sysUserDevice.getNickDeviceName());
                    sysUserDevice1.setLevel(sysUserDevice.getLevel()+1);
                    if(!exists(children,sysUserDevice1)){
                        children.add(sysUserDevice1);
                    }
                }

            }
            sysUserDevice.setChildren(children);
            children.sort((o1, o2) ->o1.getOrderNum().compareTo(o2.getOrderNum()) );
            findChildren(children,sysUserDevices);
        }
    }

    private boolean exists(List<SysUserDevice> sysUserDeviceList,SysUserDevice sysUserDevice){
        boolean exist = false;
        for(SysUserDevice sysUserDevice1:sysUserDeviceList){
            if(sysUserDevice.getId().equals(sysUserDevice1.getId())){
                exist = true;
            }
        }
        return exist;
    }
    private List<SysUserDevice> findDevicesForUser(String deviceName,Long userId){
        List<SysUserDevice> list;
/*        if(userId==1L){
            if(!"".equals(deviceName)){
                list=sysUserDeviceMapper.findPageAdmin(deviceName);
            }else{
                list=sysUserDeviceMapper.findPageByAdmin();
            }
        }else {*/
            if (!"".equals(deviceName)) {
                list = sysUserDeviceMapper.findPageDevices(deviceName,userId);
            } else {
                list = sysUserDeviceMapper.findPageByDevices(userId);
            }
       // }
        return list;
    }

  //  @Cacheable(value = "userDevice")
    @Override
    public PageResult findPage2(PageRequest pageRequest, Long userId){
        PageResult pageResult=null;
        Object name = pageRequest.getParam("deviceName");
        Map<Object, Object> params = new HashMap<>();
        params.put("id",userId);
        pageRequest.setParams(params);
        Object id = pageRequest.getParam("id");
        if(userId==1L){
            if(name!=""){
                pageResult = MybatisPageHelper.findPage(pageRequest, sysUserDeviceMapper, "findPageAdmin", name);
            }else{
                pageResult = MybatisPageHelper.findPage(pageRequest, sysUserDeviceMapper, "findPageByAdmin");
            }
        }else {
            if (name!="" ) {
                pageResult = MybatisPageHelper.findPage(pageRequest, sysUserDeviceMapper, "findPageDevices", name, id);
            } else {
                pageResult = MybatisPageHelper.findPage(pageRequest, sysUserDeviceMapper, "findPageByDevices", id);
            }
        }
        return pageResult;
    }

   // @Cacheable(value = "userDevice",key = "#id")
    @Override
    public List<SysUserDevice> findByUserId(Long userId) {
        List<SysUserDevice> sysUserDevices = sysUserDeviceMapper.findByUserId(userId);
       // List<SysUserDevice> sysUserDevices1 = sysUserDeviceMapper.findByUserId(userId);
       // for(SysUserDevice sud:sysUserDevices){
          //  for(SysUserDevice sud1:sysUserDevices1){
              //  if(sud.getDeviceId().equals(sud1.getDeviceId())){
                  //  sud.setNickDeviceName(sud1.getNickDeviceName());
              //  }
         //   }
      //  }
        return sysUserDevices;
    }

    @Override
    public int saveOrUpdate(SysUserDevice sysUserDevice, Long id) {

        return 1;
    }

    @Override
    public List<SysUserDevice> findByIdForUser(Long id, Long userId) {
        return sysUserDeviceMapper.findByIdForUser(id,userId);
    }

    @Override
    public List<SysUserDevice> queryDevices(Long userId) {
        return sysUserDeviceMapper.queryDevices(userId);
    }


    //  @CachePut(value = "userDevice")
    @Override
    public int save(SysUserDevice record) {

        if(record.getId() == null || record.getId() == 0) {
            //添加
            if(record.getType()==0) {
                SysDevice sysDevice = sysDeviceMapper.findDevice(record.getDeviceId());
                record.setPointNums(sysDevice.getPointNum());
            }
            record.setCreateTime(new Date());
            sysUserDeviceMapper.insertUserDevice(record);

        }else{
            //修改
            sysUserDeviceMapper.updateUserDevice(record);
        }
        return 1;
    }

    @Override
    public int delete(SysUserDevice record) {
        List<SysDevicePointUnit> sysDevicePointUnits = sysPointUnitMapper.findAllById(record.getId());
        for(SysDevicePointUnit sysDevicePointUnit : sysDevicePointUnits){
            sysPointUnitMapper.deleteForId(sysDevicePointUnit.getId());
        }
        return sysUserDeviceMapper.deleteByDevice(record.getId());
    }

    private int deleteUserDevice(SysUserDevice sysUserDevice,Long userId){

        Long parentDeviceId = sysUserDevice.getId();

        List<SysUserDevice> sysUserDevices = sysUserDeviceMapper.findListForParentDeviceId(parentDeviceId);
        for(SysUserDevice sysUserDevice1:sysUserDevices){
            Long userDeviceId = sysUserDevice1.getId();
            sysPointUnitMapper.deleteForUserDeviceId(userDeviceId);
            sysUserDeviceMapper.deleteByDevice(userDeviceId);
        }

        return sysUserDeviceMapper.deleteByDevice(sysUserDevice.getId());
    }

    @Override
    public int deleteUserDevices(List<SysUserDevice> records, Long userId) {
        for(SysUserDevice sysUserDevice:records){
            deleteUserDevice(sysUserDevice,userId);
        }
        return 1;
    }

    @Override
    public List<SysUser> getUserForIdent(String deviceIdent, Long userId) {
        //获取自己创建的用户列表
        List<SysUser> sysUsers = sysUserMapper.findCreateId(userId);
        //获取标识符为deviceIdent的用户设备列表
        List<SysUserDevice> sysUserDevices = sysUserDeviceMapper.findDeviceForIdentAndUserId(userId,deviceIdent);
        List<SysUser> sysUsers1=new ArrayList<>();
        //将用户Id与有用户设备列表的userId相等的用户返回
        for(SysUser sysUser:sysUsers){
            for(SysUserDevice sysUserDevice:sysUserDevices){
                if(sysUser.getId().equals(sysUserDevice.getUserId())){
                    sysUsers1.add(sysUser);
                }
            }
        }
        return sysUsers1;
    }

    @Override
    public int upUserForDevice(List<SysUser> sysUserList, Long selfId) {
        String deviceIdent="";
        String nickDeviceName="" ;
        Long deviceParentId =0L;
        Long pointNums =0L;
        //设备标识
        if(sysUserList.get(0).getUserDevice()!=null) {
         deviceIdent = sysUserList.get(0).getUserDevice().getDeviceIdent();
            nickDeviceName = sysUserList.get(0).getUserDevice().getNickDeviceName();
            deviceParentId = sysUserList.get(0).getUserDevice().getParentDeviceId();
            pointNums = sysUserList.get(0).getUserDevice().getPointNums();
        }
        //根据用户设备标识获取绑定的用户列表
        List<SysUserDevice> sysUserDevicess = sysUserDeviceMapper.getDeviceForIdent(deviceIdent);
        //获取自己创建的用户列表
        List<SysUser> sysUsers= sysUserMapper.findCreateId(selfId);
        List<SysUser> sysUsers1=  new ArrayList<>();
        for(SysUserDevice sysUserDevice:sysUserDevicess){
            for(SysUser sysUser:sysUsers){
                if(sysUserDevice.getUserId().equals(sysUser.getId())){
                    sysUsers1.add(sysUser);
                }
            }
        }

        boolean dr=sysUsers1.isEmpty();           //判断用户列表是否为空
        List<Long> ar = new ArrayList<>();           //要删除的设备集合
        List<Long> br = new ArrayList<>();        //要添加的设备集合
        List<Long> cr = new ArrayList<>();
        if(dr && sysUserList.get(0).getId()!=0){                                     //如果该设备标识查询的用户列表是空的，则进入
            for (int i =0;i<sysUserList.size();i++){  //循环遍历设备上报要增加的User
                br.add(sysUserList.get(i).getId());        //写入增加的集合
            }
        }else if(sysUserList.get(0).getId()==0){          //如果要增加的集合是空的
            for(SysUser sysUser:sysUsers1){   //循环遍历该设备标识查询的User
                ar.add(sysUser.getId());                 //写入删除集合
            }
        }
        else {
            for (int j =0;j<sysUserList.size();j++) {     //否则遍历要增加的User
                for (SysUser sysUser : sysUsers1) {        //遍历该Id下原有的User
                    if (sysUser.getId().equals(sysUserList.get(j).getId())) {     //判断上报的用户Id与获取的查询的用户Id是否相同
                        cr.add(sysUserList.get(j).getId());                 //相同则把上报的deviceId写入中间容器中
                    }
                }
            }
            for (int j =0;j<sysUserList.size();j++) {             //将上报的用户Id写入增加集合中
                br.add(sysUserList.get(j).getId());
            }
            for (Long f : cr) {                                 //将上报的与查询的，相同的移除
                br.remove(f);
            }
            for(SysUser sysd : sysUsers1){           //遍历要删除的
                ar.add(sysd.getId());
            }
            for(Long u:cr){
                ar.remove(u);
            }

        }
        if(ar.size() != 0){
            for(Long userId:ar) {
                //删除操作
                sysUserMapper.deleteUserDevice(userId, deviceIdent);
            }
        }

        if(br.size() != 0) {
            //增加操作
            for(Long userId:br) {
                SysUserDevice sysUserDevice = new SysUserDevice();
                sysUserDevice.setType(1L);
                sysUserDevice.setOrderNum(0L);
                sysUserDevice.setUserId(userId);
                sysUserDevice.setCreateId(selfId);
                //     sysUserDevice.setDeviceIdent(deviceIdent);
                sysUserDevice.setCreateTime(new Date());
                sysUserDevice.setNickDeviceName(nickDeviceName);
                sysUserDevice.setParentDeviceId(deviceParentId);
                sysUserDevice.setDeviceIdent(deviceIdent);
                sysUserDevice.setPointNums(pointNums);
                sysUserMapper.insertUserDevice(sysUserDevice);

            }
            }

        //
        return 0;
    }

    @Override
    public int delete(List<SysUserDevice> records) {
        for(SysUserDevice sysUserDevice:records){
            delete(sysUserDevice);
        }
        return 1;
    }

    @Override
    public SysUserDevice findById(Long id) {
        return null;
    }

    @Override
    public PageResult findPage(PageRequest pageRequest) {
        return null;
    }
}
